home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 681 / term / source.lha / termRaster.c < prev    next >
C/C++ Source or Header  |  1992-05-14  |  11KB  |  629 lines

  1. /*
  2. **    $Id: termRaster.c,v 1.3 92/05/14 09:05:39 olsen Sta Locker: olsen $
  3. **    $Revision: 1.3 $
  4. **    $Date: 92/05/14 09:05:39 $
  5. **
  6. **    Screen character (raster) buffering routines
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* RasterMarkArea(WORD Column,WORD Line,WORD Length):
  15.      *
  16.      *    Mark an area in the term Buffer window.
  17.      */
  18.  
  19. STATIC VOID __regargs
  20. RasterMarkArea(WORD Column,WORD Line,WORD Length)
  21. {
  22.     STATIC WORD OldColumn = -1,OldLine = -1,OldLength = -1;
  23.  
  24.     if(OldColumn != Column || OldLine != Line || OldLength != Length)
  25.     {
  26.         if(OldColumn != -1)
  27.             ClipBlit(RPort,0,0,RPort,OldColumn * 8,OldLine * 8,OldLength * 8,8,0x50);
  28.  
  29.         if(Column != -1)
  30.             ClipBlit(RPort,0,0,RPort,Column * 8,Line * 8,Length * 8,8,0x50);
  31.     }
  32.  
  33.     OldColumn    = Column;
  34.     OldLine        = Line;
  35.     OldLength    = Length;
  36. }
  37.  
  38.     /* RasterClip():
  39.      *
  40.      *    Put a character raster portion into the clipboard.
  41.      */
  42.  
  43. VOID
  44. RasterClip(BYTE SingleChar,BYTE Xerox)
  45. {
  46.     struct IntuiMessage    *Massage;
  47.     ULONG             Code,Class;
  48.     BYTE             SkipLoop = FALSE;
  49.     LONG             ThisLine,ThisColumn,MyColumn,SomeColumn;
  50.     UBYTE            *TheLine;
  51.     UBYTE             Mask = RPort -> Mask;
  52.  
  53.     SetWrMsk(RPort,0xFF);
  54.  
  55.         /* Remember initial mouse position. */
  56.  
  57.     ThisColumn    = Window -> MouseX / 8;
  58.     ThisLine    = Window -> MouseY / 8;
  59.  
  60.     if(ThisColumn <= LastColumn && ThisLine <= LastLine)
  61.     {
  62.         RasterMarkArea(-1,-1,-1);
  63.  
  64.             /* Find the approriate line and its length. */
  65.  
  66.         TheLine = &Raster[RasterWidth * ThisLine];
  67.  
  68.         if(SingleChar)
  69.         {
  70.             if(TheLine[ThisColumn] && TheLine[ThisColumn] != ' ')
  71.             {
  72.                 SerWrite(&TheLine[ThisColumn],1);
  73.  
  74.                 if(Xerox)
  75.                 {
  76.                     switch(Config . SendCR)
  77.                     {
  78.                         case CR_IGNORE:    break;
  79.  
  80.                         case CR_ASCR:    SerWrite("\r",1);
  81.                                 break;
  82.  
  83.                         case CR_ASCRLF:    SerWrite("\r\n",2);
  84.                                 break;
  85.                     }
  86.                 }
  87.             }
  88.  
  89.             SetWrMsk(RPort,Mask);
  90.  
  91.             return;
  92.         }
  93.  
  94.             /* Resonable dimensions? */
  95.  
  96.         if(ThisColumn <= LastColumn)
  97.         {
  98.             MyColumn = ThisColumn;
  99.  
  100.                 /* Loop until left mouse button is release. */
  101.  
  102.             while(!SkipLoop)
  103.             {
  104.                 WaitPort(Window -> UserPort);
  105.  
  106.                 while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  107.                 {
  108.                     Class    = Massage -> Class;
  109.                     Code    = Massage -> Code;
  110.  
  111.                     ReplyMsg(Massage);
  112.  
  113.                         /* User deactivated window
  114.                          * (which strange way to do
  115.                          * this he may ever have
  116.                          * taken...).
  117.                          */
  118.  
  119.                     if(Class == IDCMP_INACTIVEWINDOW)
  120.                     {
  121.                         SkipLoop = TRUE;
  122.  
  123.                         RasterMarkArea(-1,-1,-1);
  124.  
  125.                         break;
  126.                     }
  127.  
  128.                         /* We're finished! */
  129.  
  130.                     if(Class == IDCMP_MOUSEBUTTONS && (Code & IECODE_UP_PREFIX))
  131.                     {
  132.                         SkipLoop = TRUE;
  133.  
  134.                             /* Did we get a reasonable mouse
  135.                              * position?
  136.                              */
  137.  
  138.                         if(MyColumn != ThisColumn)
  139.                         {
  140.                                 /* Preserve right order of
  141.                                  * numbers.
  142.                                  */
  143.  
  144.                             if(MyColumn < ThisColumn)
  145.                             {
  146.                                 LONG Help;
  147.  
  148.                                 Help        = ThisColumn;
  149.                                 ThisColumn    = MyColumn;
  150.                                 MyColumn    = Help;
  151.                             }
  152.  
  153.                             RasterMarkArea(-1,-1,-1);
  154.  
  155.                                 /* Clip the contents of the line to
  156.                                  * the clipboard.
  157.                                  */
  158.  
  159.                             SaveClip(&TheLine[ThisColumn],MyColumn - ThisColumn);
  160.  
  161.                             if(Xerox)
  162.                             {
  163.                                 SerWrite(&TheLine[ThisColumn],MyColumn - ThisColumn);
  164.  
  165.                                 switch(Config . SendCR)
  166.                                 {
  167.                                     case CR_IGNORE:    break;
  168.  
  169.                                     case CR_ASCR:    SerWrite("\r",1);
  170.                                             break;
  171.  
  172.                                     case CR_ASCRLF:    SerWrite("\r\n",2);
  173.                                             break;
  174.                                 }
  175.                             }
  176.                         }
  177.  
  178.                         break;
  179.                     }
  180.  
  181.                         /* The mouse has moved. */
  182.  
  183.                     if(Class == IDCMP_MOUSEMOVE)
  184.                     {
  185.                         STATIC LONG OldColumn = ~0;
  186.  
  187.                             /* Determine new mouse position. */
  188.  
  189.                         SomeColumn = MyColumn;
  190.  
  191.                         MyColumn = Massage -> MouseX / 8;
  192.  
  193.                         if((Massage -> MouseY / 8) < ThisLine)
  194.                             MyColumn = 0;
  195.  
  196.                         if((Massage -> MouseY / 8) > ThisLine)
  197.                             MyColumn = LastColumn + 1;
  198.  
  199.                             /* Don't redraw the line if nothing
  200.                              * has changed.
  201.                              */
  202.  
  203.                         if(OldColumn != MyColumn)
  204.                         {
  205.                             OldColumn = MyColumn;
  206.  
  207.                                 /* Reasonable position? */
  208.  
  209.                             if(MyColumn <= LastColumn + 1)
  210.                             {
  211.                                 if(MyColumn >= 0)
  212.                                 {
  213.                                         /* Highlight the selected
  214.                                          * area (invert).
  215.                                          */
  216.  
  217.                                     if(MyColumn != ThisColumn)
  218.                                     {
  219.                                         if(MyColumn < ThisColumn)
  220.                                             RasterMarkArea(MyColumn,ThisLine,ThisColumn - MyColumn);
  221.                                         else
  222.                                             RasterMarkArea(ThisColumn,ThisLine,MyColumn - ThisColumn);
  223.                                     }
  224.                                 }
  225.                             }
  226.                             else
  227.                                 MyColumn = SomeColumn;
  228.                         }
  229.                     }
  230.                 }
  231.             }
  232.         }
  233.     }
  234.  
  235.     SetWrMsk(RPort,Mask);
  236. }
  237.  
  238.     /* DeleteRaster():
  239.      *
  240.      *    Free the contents of the character raster.
  241.      */
  242.  
  243. VOID
  244. DeleteRaster()
  245. {
  246.     if(Raster)
  247.     {
  248.         FreeVec(Raster);
  249.  
  250.         Raster = NULL;
  251.     }
  252.  
  253.     if(RasterAttr)
  254.     {
  255.         FreeVec(RasterAttr);
  256.  
  257.         RasterAttr = NULL;
  258.     }
  259. }
  260.  
  261.     /* CreateRaster():
  262.      *
  263.      *    Create the character raster.
  264.      */
  265.  
  266. BYTE
  267. CreateRaster()
  268. {
  269.         /* Width of the screen * 2 (in characters).
  270.          * extra for Double width
  271.          */
  272.  
  273.     RasterWidth    = Window -> Width / 4;
  274.  
  275.         /* Height of the character raster. */
  276.  
  277.     RasterHeight    = Window -> Height / 8;
  278.  
  279.         /* Allocate the raster. */
  280.  
  281.     if(!(Raster = (UBYTE *)AllocVec(RasterWidth * RasterHeight,MEMF_ANY|MEMF_CLEAR)))
  282.         return(FALSE);
  283.  
  284.         /* Allocate the raster attributes. */
  285.  
  286.     if(!(RasterAttr = (UBYTE *)AllocVec(RasterHeight,MEMF_ANY|MEMF_CLEAR)))
  287.     {
  288.         FreeVec(Raster);
  289.  
  290.         Raster = NULL;
  291.  
  292.         return(FALSE);
  293.     }
  294.  
  295.     return(TRUE);
  296. }
  297.  
  298.     /* RasterEraseScreen(BYTE Mode):
  299.      *
  300.      *    Erase parts of the screen.
  301.      */
  302.  
  303. VOID __regargs
  304. RasterEraseScreen(BYTE Mode)
  305. {
  306.     WORD    First,
  307.         Last;
  308.  
  309.     switch(Mode)
  310.     {
  311.         case 1:    First    = 0;
  312.             Last    = CursorY * RasterWidth + CursorX + 1;
  313.  
  314.             memset(&RasterAttr[0],SCALE_NORMAL,CursorY + 1);
  315.  
  316.             break;
  317.  
  318.         case 2:    First    = 0;
  319.             Last    = RasterHeight * RasterWidth - 1;
  320.  
  321.             memset(&RasterAttr[0],SCALE_NORMAL,RasterHeight);
  322.  
  323.             break;
  324.  
  325.         default:First    = CursorY * RasterWidth + CursorX;
  326.             Last    = RasterHeight * RasterWidth - 1;
  327.  
  328.             memset(&RasterAttr[CursorY],SCALE_NORMAL,RasterHeight - CursorY);
  329.  
  330.             break;
  331.     }
  332.  
  333.     if(Last > First)
  334.         memset(&Raster[First],' ',Last - First);
  335. }
  336.  
  337.     /* RasterEraseLine(BYTE Mode):
  338.      *
  339.      *    Erase parts of the current cursor line.
  340.      */
  341.  
  342. VOID __regargs
  343. RasterEraseLine(BYTE Mode)
  344. {
  345.     WORD    First,
  346.         Last;
  347.  
  348.     switch(Mode)
  349.     {
  350.             /* From beginning to current cursor position. */
  351.  
  352.         case 1:    First    = CursorY * RasterWidth;
  353.             Last    = First + CursorX + 1;
  354.  
  355.             break;
  356.  
  357.             /* Entire line. */
  358.  
  359.         case 2:    First    = CursorY * RasterWidth;
  360.             Last    = First + RasterWidth - 1;
  361.  
  362.             break;
  363.  
  364.             /* From current cursor position towards end. */
  365.  
  366.         default:First    = CursorY * RasterWidth + CursorX;
  367.             Last    = (CursorY + 1) * RasterWidth - 1;
  368.  
  369.             break;
  370.     }
  371.  
  372.     if(Last > First)
  373.         memset(&Raster[First],' ',Last - First);
  374. }
  375.  
  376.     /* RasterEraseCharacters(WORD Chars):
  377.      *
  378.      *    Erase a number of characters in the current cursor
  379.      *    line.
  380.      */
  381.  
  382. VOID __regargs
  383. RasterEraseCharacters(WORD Chars)
  384. {
  385.     if(CursorX < RasterWidth - 1)
  386.     {
  387.         WORD     First,
  388.              Diff;
  389.         UBYTE    *To,
  390.             *From;
  391.  
  392.         First    = CursorY * RasterWidth + CursorX;
  393.         To    = &Raster[First];
  394.  
  395.         if(CursorX + Chars >= RasterWidth)
  396.         {
  397.             Diff = RasterWidth - 1 - CursorX;
  398.  
  399.             while(Diff-- > 0)
  400.                 *To++ = ' ';
  401.         }
  402.         else
  403.         {
  404.             From    = &Raster[First + Chars];
  405.             Diff    = RasterWidth - (CursorX + 1 + Chars);
  406.  
  407.             while(Diff--)
  408.             {
  409.                 *To++ = *From;
  410.  
  411.                 *From++ = ' ';
  412.             }
  413.         }
  414.     }
  415. }
  416.  
  417.     /* RasterClearLine(WORD Lines):
  418.      *
  419.      *    Clear and remove a number of lines.
  420.      */
  421.  
  422. VOID __regargs
  423. RasterClearLine(WORD Lines,WORD Top)
  424. {
  425.     if(Lines)
  426.     {
  427.         WORD RegionBottom;
  428.  
  429.         if(RegionSet)
  430.             RegionBottom = Bottom;
  431.         else
  432.             RegionBottom = LastLine + 1;
  433.  
  434.         if(Top + Lines >= RegionBottom)
  435.             RasterEraseScreen(0);
  436.         else
  437.         {
  438.             WORD     Max;
  439.             UBYTE    *From,
  440.                 *To;
  441.  
  442.             Max    = (RegionBottom - (Top + Lines)) * RasterWidth;
  443.  
  444.             From    = &Raster[(Top + Lines) * RasterWidth];
  445.             To    = &Raster[ Top          * RasterWidth];
  446.  
  447.             while(Max--)
  448.             {
  449.                 *To++ = *From;
  450.  
  451.                 *From++ = ' ';
  452.             }
  453.  
  454.             memset(&RasterAttr[RegionBottom - Lines],SCALE_NORMAL,Lines);
  455.         }
  456.     }
  457. }
  458.  
  459.     /* RasterInsertLine(WORD Lines):
  460.      *
  461.      *    Insert a number of lines at the current cursor line.
  462.      */
  463.  
  464. VOID __regargs
  465. RasterInsertLine(WORD Lines,WORD Top)
  466. {
  467.     if(Lines)
  468.     {
  469.         WORD RegionBottom;
  470.  
  471.         if(RegionSet)
  472.             RegionBottom = Bottom;
  473.         else
  474.             RegionBottom = LastLine + 1;
  475.  
  476.         if(Top + Lines > RegionBottom)
  477.             RasterEraseScreen(0);
  478.         else
  479.         {
  480.             WORD     From,To,
  481.                  Max;
  482.             UBYTE    *FromPtr,
  483.                 *ToPtr;
  484.  
  485.             Max    = (RegionBottom - Lines - Top) * RasterWidth;
  486.  
  487.             From    = (RegionBottom - Lines) * RasterWidth - 1;
  488.             To    =  RegionBottom          * RasterWidth - 1;
  489.  
  490.             FromPtr    = &Raster[From];
  491.             ToPtr    = &Raster[To];
  492.  
  493.             while(Max--)
  494.                 *ToPtr-- = *FromPtr--;
  495.  
  496.             memset(&Raster[Top * RasterWidth],' ',Lines * RasterWidth);
  497.         }
  498.     }
  499. }
  500.  
  501.     /* RasterScrollRegion(WORD Direction,WORD RasterTop,WORD RasterBottom,WORD RasterLines):
  502.      *
  503.      *    Scroll the contents of the character raster up/down.
  504.      */
  505.  
  506. VOID __regargs
  507. RasterScrollRegion(WORD Direction,WORD RasterTop,WORD RasterBottom,WORD RasterLines)
  508. {
  509.     WORD Dir = ABS(Direction);
  510.  
  511.     if(Dir >= RasterLines)
  512.     {
  513.             /* All that is needed is to delete the lines. */
  514.  
  515.         memset(&Raster[RasterTop * RasterWidth],' ',RasterLines * RasterWidth);
  516.     }
  517.     else
  518.     {
  519.         WORD     First,
  520.              Last,
  521.              Max,
  522.              i;
  523.         UBYTE    *From,
  524.             *To;
  525.  
  526.         Max = (RasterLines - Dir) * RasterWidth;
  527.  
  528.         if(Direction < 0)
  529.         {
  530.             First    = (RasterTop + RasterLines - Dir) * RasterWidth - 1;
  531.             Last    = (RasterTop + RasterLines    ) * RasterWidth - 1;
  532.  
  533.             From    = &Raster[First];
  534.             To    = &Raster[Last];
  535.  
  536.             while(Max--)
  537.                 *To-- = *From--;
  538.  
  539.             for(i = RasterBottom ; i >= (RasterTop + Dir) ; i--)
  540.                 RasterAttr[i] = RasterAttr[i - Dir];
  541.  
  542.             memset(&Raster[RasterTop * RasterWidth],' ',RasterWidth * Dir);
  543.  
  544.             memset(&RasterAttr[RasterTop],SCALE_NORMAL,Dir);
  545.         }
  546.         else
  547.         {
  548.             First    = RasterTop * RasterWidth + RasterWidth * Dir;
  549.             Last    = RasterTop * RasterWidth;
  550.  
  551.             From    = &Raster[First];
  552.             To    = &Raster[Last];
  553.  
  554.             while(Max--)
  555.                 *To++ = *From++;
  556.  
  557.             memset(&Raster[(RasterBottom - Dir) * RasterWidth],' ',RasterWidth * Dir);
  558.  
  559.             for(i = RasterTop ; i <= (RasterBottom - Dir) ; i++)
  560.                 RasterAttr[i] = RasterAttr[i + Dir];
  561.  
  562.             memset(&RasterAttr[RasterBottom - Dir],SCALE_NORMAL,Dir);
  563.         }
  564.     }
  565. }
  566.  
  567.     /* RasterShiftChar(WORD Size):
  568.      *
  569.      *    Shift the characters following the current cursor
  570.      *    position Size characters to the right.
  571.      */
  572.  
  573. VOID __regargs
  574. RasterShiftChar(WORD Size)
  575. {
  576.     WORD     i,
  577.          First;
  578.     UBYTE    *From,
  579.         *To;
  580.  
  581.     if(CursorX + Size >= RasterWidth - 1)
  582.     {
  583.         i    = RasterWidth - 1 - CursorX;
  584.         To    = &Raster[CursorY * RasterWidth + CursorX];
  585.  
  586.         while(i-- > 0)
  587.             *To++ = ' ';
  588.     }
  589.     else
  590.     {
  591.         First    = (CursorY + 1) * RasterWidth - 1;
  592.         To    = &Raster[First];
  593.  
  594.         From    = &Raster[First - Size];
  595.         i    = RasterWidth - Size;
  596.  
  597.         while(i-- > CursorX)
  598.             *To-- = *From--;
  599.  
  600.         To    = &Raster[CursorY * RasterWidth + CursorX];
  601.  
  602.         while(Size--)
  603.             *To++ = ' ';
  604.     }
  605. }
  606.  
  607.     /* RasterPutString(UBYTE *String,WORD Length):
  608.      *
  609.      *    Put a string into the character raster.
  610.      */
  611.  
  612. VOID __regargs
  613. RasterPutString(UBYTE *String,WORD Length)
  614. {
  615.     if(Length == 1)
  616.     {
  617.         if(CursorX + 1 < RasterWidth)
  618.             Raster[CursorY * RasterWidth + CursorX] = String[0];
  619.     }
  620.     else
  621.     {
  622.         if(CursorX + Length >= RasterWidth)
  623.             Length = RasterWidth - 1 - CursorX;
  624.  
  625.         if(Length > 0)
  626.             memcpy(&Raster[CursorY * RasterWidth + CursorX],String,Length);
  627.     }
  628. }
  629.